package cn.mrlong.idcardphoto.camera;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import cn.mrlong.idcardphoto.R;

public class CameraActivity extends Activity implements View.OnClickListener {
    public final static int IDCARD_FRONT = 1;//身份证正面
    public final static int IDCARD_BACK = 2;//身份证反面
    public final static String TAKE_TYPE = "take_type";//拍摄类型标记
    public final static String IMAGE_PATH = "image_path";//图片路径标记
    public final static int REQ_CODE = 11;//请求码
    public final static int RES_CODE = 12;//结果码
    public final static int PERMISSION_CODE = 13;//权限请求码

    public static boolean isToastNotice = true;//是否通知
    public static int mType;//拍摄类型  默认正面

    private CameraPreview mCameraPreview;
    private LinearLayout mLlCameraCropContainer;
    private ImageView mIvCameraCrop;
    private ImageView mIvCameraFlash;
    private LinearLayout mLlCameraOption;
    private LinearLayout mLlCameraResult;
    private TextView mViewCameraCropBottom;
    private Bitmap mCropBitmap;
    private ImageView resPicPre;
    private ImageView iv_camera_close;
    private ImageView iv_camera_take;
    private ImageView iv_camera_result_ok;
    private ImageView iv_camera_result_cancel;

    /**
     * 打开相机
     *
     * @param activity
     * @param type     相框类型
     */
    public static void openCamera(Activity activity, int type) {
        Intent intent = new Intent(activity, CameraActivity.class);
        intent.putExtra(TAKE_TYPE, type);
        activity.startActivityForResult(intent, REQ_CODE);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        boolean flag = checkPermissionFirst(this, PERMISSION_CODE,
                new String[]{
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.CAMERA});
        if (flag) {
            init();
        }
    }

    private void init() {
        setContentView(R.layout.activity_camera);
        mType = getIntent().getIntExtra(TAKE_TYPE, 1);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//设置横向
        initView();
        initListener();

    }


    private void initView() {
        findView();
        //获取屏幕最小边，设置为cameraPreview较窄的一边
        float screenMinSize = Math.min(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
        //根据screenMinSize，计算出cameraPreview的较宽的一边，长宽比为标准的16:9
        float maxSize = screenMinSize / 9.0f * 16.0f;
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams((int) maxSize, (int) screenMinSize);
        layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        mCameraPreview.setLayoutParams(layoutParams);

        float height = (int) (screenMinSize * 0.75);
        float width = (int) (height * 75.0f / 47.0f);
        LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams((int) width, ViewGroup.LayoutParams.MATCH_PARENT);
        LinearLayout.LayoutParams cropParams = new LinearLayout.LayoutParams((int) width, (int) height);
        mLlCameraCropContainer.setLayoutParams(containerParams);
        mIvCameraCrop.setLayoutParams(cropParams);

        switch (mType) {
            case IDCARD_FRONT:
                mIvCameraCrop.setImageResource(R.mipmap.camera_idcard_front);
                break;
            case IDCARD_BACK:
                mIvCameraCrop.setImageResource(R.mipmap.camera_idcard_back);
                break;
        }
    }

    private void findView() {
        mCameraPreview = findViewById(R.id.camera_preview);
        mLlCameraCropContainer = findViewById(R.id.ll_camera_crop_container);
        mIvCameraCrop = findViewById(R.id.iv_camera_crop);
        mIvCameraFlash = findViewById(R.id.iv_camera_flash);
        mLlCameraOption = findViewById(R.id.ll_camera_option);
        mLlCameraResult = findViewById(R.id.ll_camera_result);
        resPicPre = findViewById(R.id.iv_camera_result_pic);
        mViewCameraCropBottom = findViewById(R.id.view_camera_crop_bottom);
        iv_camera_close = findViewById(R.id.iv_camera_close);
        iv_camera_take = findViewById(R.id.iv_camera_take);
        iv_camera_result_ok = findViewById(R.id.iv_camera_result_ok);
        iv_camera_result_cancel = findViewById(R.id.iv_camera_result_cancel);
    }

    private void initListener() {
        mCameraPreview.setOnClickListener(this);
        mIvCameraFlash.setOnClickListener(this);
        iv_camera_close.setOnClickListener(this);
        iv_camera_result_ok.setOnClickListener(this);
        iv_camera_take.setOnClickListener(this);
        iv_camera_result_cancel.setOnClickListener(this);
    }

    /**
     * 检查权限
     *
     * @param context
     * @param requestCode 请求码
     * @param permission  权限数组
     * @return
     */
    public static boolean checkPermissionFirst(Context context, int requestCode, String[] permission) {
        List<String> permissions = new ArrayList<String>();
        for (String per : permission) {
            int permissionCode = ActivityCompat.checkSelfPermission(context, per);
            if (permissionCode != PackageManager.PERMISSION_GRANTED) {
                permissions.add(per);
            }
        }
        if (!permissions.isEmpty()) {
            ActivityCompat.requestPermissions((Activity) context, permissions.toArray(new String[permissions.size()]), requestCode);
            return false;
        } else {
            return true;
        }
    }

    /**
     * 权限检查返回
     *
     * @param requestCode  请求码
     * @param permissions  权限数组
     * @param grantResults 请求权限结果数组
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        boolean permissionsFlag = true;
        for (int i = 0; i < permissions.length; i++) {
            if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                permissionsFlag = false;
                if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {
                    showNotice("请手动打开该应用需要的权限");
                    isToastNotice = false;
                }
            }
        }
        isToastNotice = true;
        if (permissionsFlag) {
            init();
        } else {
            this.finish();
        }

    }

    @Override
    public void onClick(View view) {
        int i = view.getId();

        if (i == R.id.camera_preview) {//预览 自动聚焦
            mCameraPreview.autoFocus();
        } else if (i == R.id.iv_camera_close) {//关闭
            this.finish();
        } else if (i == R.id.iv_camera_take) {//拍照
            takePic();
        } else if (i == R.id.iv_camera_flash) {//闪光灯控制
            boolean isOpen = mCameraPreview.switchFlashLight();
            mIvCameraFlash.setImageResource(isOpen ? R.mipmap.camera_flash_on : R.mipmap.camera_flash_off);
        } else if (i == R.id.iv_camera_result_ok) {//ok
            confirm();
        } else if (i == R.id.iv_camera_result_cancel) {//cancel
            mCameraPreview.setEnabled(true);
            mCameraPreview.startPreview();
            mIvCameraFlash.setImageResource(R.mipmap.camera_flash_off);
            setLayout();
        }
    }

    /**
     * 设置裁剪布局
     */
    private void setCropLayout() {
        mIvCameraCrop.setVisibility(View.GONE);
        mCameraPreview.setVisibility(View.GONE);
        mLlCameraOption.setVisibility(View.GONE);
        resPicPre.setVisibility(View.VISIBLE);
        mLlCameraResult.setVisibility(View.VISIBLE);
        mViewCameraCropBottom.setText("");
    }


    private void setLayout() {
        mIvCameraCrop.setVisibility(View.VISIBLE);
        mCameraPreview.setVisibility(View.VISIBLE);
        mLlCameraOption.setVisibility(View.VISIBLE);
        resPicPre.setVisibility(View.GONE);
        mLlCameraResult.setVisibility(View.GONE);
        mViewCameraCropBottom.setText("触摸屏幕对焦");
        mCameraPreview.autoFocus();
    }

    /**
     * 保存图片并返回
     */
    public static String FILE_PATH = "";//文件夹根目录

    private void confirm() {

        if (!"".equals(FILE_PATH)) {
            String imgPath = "";
            File pathS = new File(FILE_PATH.toString());
            if (!pathS.exists()) {
                pathS.mkdirs();
            }
            imgPath = pathS.getPath();
            StringBuffer name = new StringBuffer();
            if (mType == IDCARD_FRONT) {
                name.append("idcard.jpg");
            } else {
                name.append("idcardback.jpg");
            }
            File realFile = new File(imgPath, name.toString());
            System.out.println("=====================================>" + realFile.getAbsolutePath());
            //存储数据
            boolean flag = saveFile(mCropBitmap, realFile, Bitmap.CompressFormat.JPEG, false);
            if (flag) {
                Intent intent = new Intent();
                intent.putExtra(CameraActivity.IMAGE_PATH, realFile.getAbsolutePath());
                setResult(RES_CODE, intent);
                finish();
            }
        } else {
            showNotice("没有设置路径");
        }
    }

    /**
     * 保存图片
     */
    public boolean saveFile(Bitmap src, File file, Bitmap.CompressFormat format, boolean recycle) {
        if (isEmptyBitmap(src)) {
            return false;
        }
        OutputStream os = null;
        boolean ret = false;
        try {
            os = new BufferedOutputStream(new FileOutputStream(file));
            ret = src.compress(format, 100, os);
            if (recycle && !src.isRecycled()) {
                src.recycle();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != os) {
                try {
                    os.flush();
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    os = null;
                }

            }
        }
        return ret;
    }

    private static boolean isEmptyBitmap(Bitmap src) {
        return src == null || src.getWidth() == 0 || src.getHeight() == 0;
    }

    private void showNotice(String msg) {
        if (isToastNotice) {
            Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
            Log.e(this.getClass().getName() + "==>", msg);
        }
    }

    /**
     * 拍照
     */
    private void takePic() {
        mCameraPreview.setEnabled(false);//关闭点击
        mCameraPreview.takePic(new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(final byte[] data, Camera camera) {
                camera.stopPreview();
                new Thread() {
                    @Override
                    public void run() {
                        super.run();
                        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

                        /*计算裁剪位置*/
                        float left, top, right, bottom;
                        left = ((float) mLlCameraCropContainer.getLeft() - (float) mCameraPreview.getLeft()) / (float) mCameraPreview.getWidth();
                        top = (float) mIvCameraCrop.getTop() / (float) mCameraPreview.getHeight();
                        right = (float) mLlCameraCropContainer.getRight() / (float) mCameraPreview.getWidth();
                        bottom = (float) mIvCameraCrop.getBottom() / (float) mCameraPreview.getHeight();

                        /*自动裁剪*/
                        mCropBitmap = Bitmap.createBitmap(bitmap,
                                (int) (left * (float) bitmap.getWidth()),
                                (int) (top * (float) bitmap.getHeight()),
                                (int) ((right - left) * (float) bitmap.getWidth()),
                                (int) ((bottom - top) * (float) bitmap.getHeight()));

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (null != mCropBitmap) {
                                    resPicPre.setImageBitmap(mCropBitmap);
                                }
                                setCropLayout();
                            }
                        });
                    }
                }.start();
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mCameraPreview) {
            mCameraPreview.onStop();
        }
    }

    public static String getImagePath(Intent data) {
        if (data != null) {
            return data.getStringExtra(IMAGE_PATH);
        }
        return "";
    }

    public static void setPath(String path) {
        FILE_PATH = path;
    }
}
